//
//  CMTimer.swift
//  COM
//
//  Created by 韩笑 on 2020/4/13.
//  Copyright © 2020 韩笑. All rights reserved.
//

import Foundation

public enum TimeType {
    case second
    case time
    case timehms
    case countup
}

open class CMTimer {
    
    public var timeType : TimeType = .second
    
    // 时间间隔
    public var timeInterVal : TimeInterval = 1
    // 总时间,用于计算剩余时间
    public var second : Double = 60
    
    // 一个时间间隔回调
    public var handler : (( _ time : String)->Void)?
    public var timerHandler : (( _ time : String, _ surplusTime : Double)->Void)?
    public var countupHandler : (( _ time : Double)->Void)?
    
    // 完成回调
    public var complete : (()-> Void)?
    // 是否支持后台
    public var isSupportBackground = false
    
    // 经过多少秒
    private var countupSecond: Double = 0
    
    private var timer: Timer?
    public init() { }
    
    deinit {
        stopTimer()
    }
}

public extension CMTimer {
    func startTimer() {
        countupSecond = 0
        guard timer == nil else { return }
        timer = Timer.scheduledTimer(timeInterval: timeInterVal, target: self, selector: #selector(updateSecond), userInfo: nil , repeats: true)
        
        #if !os(OSX)
        if (!isSupportBackground) { return }
        let app = UIApplication.shared
        var bgTask: UIBackgroundTaskIdentifier?
        app.beginBackgroundTask {
            DispatchQueue.main.async {
                if let _ = bgTask, bgTask != .invalid
                { bgTask = .invalid }
            }
        }
        
        let queue = DispatchQueue.global(qos: .default)
        queue.async {
            DispatchQueue.main.async {
                if bgTask != .invalid
                {  bgTask = .invalid }
            }
        }
        #endif
    }
    
    func stopTimer() {
        if timer == nil { return }
        
        timer?.invalidate()
        timer = nil
    }
}

private extension CMTimer {
    
    @objc func updateSecond() {
        if timeType == .countup {
            countupSecond += timeInterVal
            countupHandler?(countupSecond)
            return
        }
        
        guard second > 1 else {
            stopTimer()
            if handler != nil {
                switch timeType {
                case .second:
                    handler!("0")
                case .time:
                    handler!("00:00")
                case .timehms:
                    handler!("00:00:00")
                    timerHandler?("00:00:00", second)
                case .countup:
                    break
                }
            }
            complete?()
            return }
        
        second -= timeInterVal
        
        switch timeType {
        case .second:
            handler?("\(second)")
        case .time:
            let time = String(format: "%02d:%02d", Int(second) / 60, Int(second) % 60)
            handler?("\(time)")
        case .timehms:
            let time = String(format: "%02d:%02d:%02d", Int(second) / 3600, Int(second) % 3600 / 60, Int(second) % 60)
            handler?("\(time)")
            timerHandler?(time, second)
        case .countup:
            break
        }
    }
}
